package multi_thread.basic;

/**
 * Description: 学习 synchronized 关键字
 * https://www.cnblogs.com/skywang12345/p/3479202.html
 *
 * @author Cheng Jun
 * @version 1.0
 * @date 2019/10/29 11:16
 * 第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时，其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
 * 第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时，其他线程仍然可以访问“该对象”的非同步代码块。
 * 第三条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时，其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
 * 在java中，每一个对象有且仅有一个同步锁。这也意味着，同步锁是依赖于对象而存在。锁类的时候，其实锁的是 类对象 ***.class
 */
public class SynchronizedExample {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        //添加线程名 t0，t1
        Thread thread0 = new Thread(myRunnable, "t0");
        Thread thread1 = new Thread(myRunnable, "t1");
        thread0.start();
        thread1.start();
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " loop " + i);
                test(Thread.currentThread().getName());
            }
        }
    }

    void test (String  threadName){
        System.out.println("test method===" + threadName);
    }
}

class TestExample {
    // static synchronized 类锁
    public static synchronized void say() {
        System.out.println("class method start");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("class method over");
    }

    // 类的对象锁，就是类锁
    public void sayAgain() {
        synchronized (TestExample.class) {
            System.out.println("object method sayAgain");
        }
    }

    // 对象锁
    public synchronized void doAgain() {
        System.out.println("object method doAgain");
    }
}
